home *** CD-ROM | disk | FTP | other *** search
- PAGE
- TITLE DPFILE
- ;
- ; (C)COPYRIGHT 1983 - REAL TIME CONCEPTS, INC.
- ;
- ; AUTHOR: THOMAS V. CARTER
- ;
- ; PC DOS FILE DUMP UTILITY PROGRAM
- ;
- ; ALLOCATE THE STACK WORK AREA
- ;
- STACKS SEGMENT PARA STACK 'STACK'
- ;
- DB 50 DUP('$$')
- ;
- STACKS ENDS
- ;
- PAGE
- ;
- ; ALLOCATE THE WORKING STORAGE SEGMENT
- ;
- WSTORE SEGMENT PARA PUBLIC 'DATA'
- ;
- ; ALLOCATE THE FILE NAME OPERATOR PROMPT
- ;
- FILNAM DB 'File name = '
- DB '$'
- ;
- ; ALLOCATE THE BLOCK NUMBER TEXT AND WORK AREAS
- ;
- BLKNUM DB 'Block Number = '
- ;
- BCOUNT DB '0000'
- DW 0A0DH
- DW 0A0DH
- DB '$'
- ;
- ; ALLOCATE THE FILE OPEN ERROR ERROR MESSAGE
- ;
- OPNERM DB 'File open error'
- DW 0A0DH
- DB '$'
- ;
- ; ALLOCATE THE FILE NOT FOUND ERROR MESSAGE
- ;
- NOFILE DB 'File not found'
- DW 0A0DH
- DB '$'
- ;
- ; DEFINE CARRIAGE RETURN AND LINE FEED CHARACTERS
- ;
- CRLFLN DW 0A0DH
- DB '$'
- ;
- ; BINARY TO HEXADECIMAL CONVERSION TABLE
- ;
- ASCIIT DB '0123456789ABCDEF'
- ;
- PAGE
- ;
- ; ALLOCATE FORM FEED CHARACTER
- ;
- FMFEED DW 0A0DH
- DB 0CH
- DB '$'
- ;
- ; ALLOCATE THE I/O BUFFER // 512 BYTES PER BLOCK
- ;
- FILBUF DB 512 DUP(' ')
- ;
- ;ALLOCATE THE FILESPEC INPUT STRUCTURE
- ;
- INPNAM DB 15
- DB 0
- DB 15 DUP(' ')
- ;
- ; ALLOCATE THE FILE DUMP PRINT LINE
- ;
- DPLINE DB 78 DUP(' ')
- DW 0A0DH
- ;
- ; ALLOCATE THE HEXADECIMAL BUFFER OFFSET COUNTER
- ;
- HEXCNT DW 0
- ;
- ;DEFINE BINARY TO DECIMAL DIVISORS
- ;
- BINDEC DW 1000
- DW 100
- DW 10
- ;
- WSTORE ENDS
- PAGE
- ;
- ; PC DOS FILE DUMP UTILITY PROGRAM
- ;
- CODSEG SEGMENT PARA PUBLIC 'CODE'
- ;
- DPFILE PROC FAR
- ASSUME CS:CODSEG ;CS = CODE SGEMENT
- ASSUME DS:WSTORE ;DS = DATA SEGMENT
- ASSUME SS:STACKS ;SS = STACK SEGMENT
- ;
- ; INITIALIZE THE PROGRAM ENVIRONMENT
- ;
- PUSH DS ;SAVE PROGRAM PREFIX SEGMENT
- SUB AX,AX ;AX = ZERO // SET FOR STACK
- MOV BP,AX ;BP = ZERO // STACK START
- MOV [BP],AX ;SETUP BLOCK NUMBER ZERO
- PUSH AX ;PUSH AX (ZERO) ON STACK
- MOV AX,WSTORE ;AX = WORKING STORAGE SEGMENT
- MOV DS,AX ;DS = WORKING STORAGE SEGMENT
- ;
- ; DISPLAY THE FILE NAME PROMPT TO THE OPERATOR
- ;
- MOV DX,OFFSET FILNAM ;DX = PROMPT OFFSET ADDRESS
- MOV AH,09H ;AH = 9 = DISPLAY PROMPT
- INT 21H ;CALL DOS FOR SERVICE
- ;
- ; ACQUIRE THE OPERATOR RESPONSE // FILESPEC
- ;
- MOV DX,OFFSET INPNAM ;DX = SEGMENT OFFSET ANSWER
- MOV AH,0AH ;AH = A = KEYBOARD INPUT
- INT 21H ;CALL DOS FOR SERVICE
- ;
- ; SEND CARRIAGE RETURN AND LINE FEED FOR APPEARANCES
- ;
- MOV DX,OFFSET CRLFLN ;DX = CR/LF OFFSET ADDRESS
- MOV AH,09H ;AH = 9 = DISPLAY CR AND LF
- INT 21H ;CALL DOS FOR SERVICE
- ;
- ; PARSE THE OPERATOR SPECIFIED FILESPEC
- ;
- MOV SI,OFFSET INPNAM+2 ;SI = FILESPEC OFFSET ADDRESS
- MOV DI,5CH ;DI = 1ST PROGRAM PREFIX FCB
- SUB AL,AL ;AL = ZERO
- MOV AH,29H ;PARSE THE RECEIVED FILE NAME
- INT 21H ;CALL DOS FOR SERVICE
- PAGE
- ;
- ; FILESPEC PARSED (1ST PROGRAM PREFIX FCB) // OPEN THE FILE
- ;
- PUSH DS ;SAVE THE DATA SEGMENT REGISTER
- ;
- MOV DX,5CH ;DX = 1ST PROGRAM PREFIX FCB
- MOV AX,ES ;AX = PROGRAM PREFIX SEGMENT
- MOV DS,AX ;DS = PROGRAM PREFIX SEGMENT
- MOV AH,0FH ;AH = F = OPEN THE FILE
- INT 21H ;CALL DOS FOR SERVICE
- ;
- POP DS ;RESTORE DATA SEGMENT REGISTER
- ;
- CMP AL,0 ;AL = OPEN FILE RETURN STATUS
- JE DPF010 ;BRANCH IF SUCCESSFUL OPEN
- ;
- ; FILE OPEN ERROR - NOTIFY THE OPERATOR AND TERMINATE
- ;
- MOV DX,OFFSET OPNERM ;DX = OPEN ERROR MESSAGE OFFSET
- MOV AH,09H ;AH = 9 = DISPLAY ERROR MESSAGE
- INT 21H ;CALL DOS FOR SERVICE
- RET ;TERMINATE PROGRAM EXECUTION
- ;
- ; SEND CARRIAGE RETURN AND LINE FEED FOR APPEARANCES
- ;
- DPF010:
- MOV DX,OFFSET CRLFLN ;DX = CR/LF OFFSET ADDRESS
- MOV AH,09H ;AH = 9 = DISPLAY CR AND LF
- INT 21H ;CALL DOS FOR SERVICE
- ;
- ; SETUP THE DATA TRANSFER ADDRESS (DTA)
- ;
- MOV DX,OFFSET FILBUF ;DX = I/O BUFFER OFFSET ADDRESS
- MOV AH,1AH ;AH = 1A = SETUP DTA
- INT 21H ;CALL DOS FOR SERVICE
- ;
- ; INITIALIZE THE 1ST PROGRAM PREFIX FILE CONTROL BLOCK
- ;
- MOV DI,5CH ;DI = FCB OFFSET ADDRESS
- MOV AX,512 ;AX = 512 = RECORD SIZE
- MOV ES:[DI+14],AX ;SETUP LOGICAL RECORD SIZE
- SUB AX,AX ;AX = ZERO
- MOV ES:[DI+32],AX ;SETUP RANDOM RECORD NUMBER
- MOV ES:[DI+34],AX ;SETUP RANDOM RECORD NUMBER
- MOV ES:[DI+36],AL ;SETUP RANDOM RECORD NUMBER
- PAGE
- ;
- ; SETUP TO CLEAR THE FILE I/O BUFFER
- ;
- DPF020:
- MOV CX,256 ;CX = LOOP CONTROL COUNTER
- MOV DI,OFFSET FILBUF ;DI = I/O BUFFER OFFSET ADDRESS
- SUB AX,AX ;AX = ZEROS
- ;
- ; SET THE CONTENTS OF THE I/O BUFFER TO BINARY ZEROS
- ;
- DPF030:
- MOV [DI],AX ;SET I/O BUFFER TO BINARY ZEROS
- ADD DI,2 ;INCREMENT DI TO NEXT WORD
- LOOP DPF030 ;LOOP FOR ALL BUFFER WORDS
- ;
- ; READ EACH 512 BYTE BLOCK OF THE FILE // RANDOM BLOCK READ
- ;
- PUSH DS ;SAVE DATA SEGMENT REGISTER
- MOV AX,ES ;AX = PROGRAM PREFIX SEGMENT
- MOV DS,AX ;DS = PROGRAM PREFIX SEGMENT
- MOV DX,5CH ;DX = 1ST PROGRAM PREFIX FCB
- MOV CX,1 ;CX = NUMBER OF RECORDS
- MOV AH,27H ;AH = 27 = RANDOM BLOCK READ
- INT 21H ;CALL DOS FOR SERVICE
- POP DS ;RESTORE DATA SEGMENT REGISTER
- ;
- CMP AL,0 ;VERIFY DISK READ COMPLETION
- JE DPF040 ;BRANCH IF SUCCESSFUL READ
- CMP CX,0 ;CHECK FOR PARTIAL BLOCK
- JNE DPF040 ;BRANCH IF DATA IN BUFFER
- ;
- RET ;TERMINATE PROGRAM EXECUTION
- ;
- ; CONVERT DATA TO DISPLAYABLE ASCII AND DISPLAY
- ;
- DPF040:
- MOV DI,OFFSET BCOUNT ;DI = BLOCK COUNT ADDRESS
- MOV AX,[BP] ;AX = CURRENT BLOCK COUNT
- INC AX ;INCREMENT BLOCK COUNT
- MOV [BP],AX ;SAVE NEW BLOCK COUNT
- DEC AX ;DECREMENT BLOCK COUNT
- CALL BDCONV ;BINARY TO DECIMAL CONVERSION
- MOV DX,OFFSET BLKNUM ;DX = BLOCK NUMBER MESSAGE
- MOV AH,09H ;AH = 9 = DISPLAY BLOCK NUMBER
- INT 21H ;CALL DOS FOR SERVICE
- MOV SI,OFFSET FILBUF ;SI = FILE I/O BUFFER ADDRESS
- MOV DI,OFFSET DPLINE+12 ;DI = HEXADECIMAL DISPLAY AREA
- MOV BP,OFFSET DPLINE+62 ;BP = ASCII DISPLAY AREA
- MOV CX,32 ;CX = NUMBER OF 16 BYTE LINES
- PUSH CX ;SAVE CX REGISTER ON THE STACK
- MOV CX,16 ;CONVERSION LOOP COUNTER
- ;
- PAGE
- ;
- ; CONVERT A BYTE OF INPUT DATA TO HEXADECIMAL
- ;
- DPF050:
- CMP CX,8 ;HALF OF LINE CONVERTED?
- JNE DPF060 ;BRANCH TO CONTINUE - NOT HALF
- DEC DI ;DECREMENT LINE POSITION INDEX
- MOV AL,'-' ;MOVE A DASH TO SEPARATE HALFS
- MOV [DI],AL ;MOVE A DASH TO SEPARATE HALFS
- INC DI ;INCREMENT LINE POSITION INDEX
- ;
- ; SAVE CX ON THE STACK AND PROCESS NEXT BYTE
- ;
- DPF060:
- PUSH CX ;SAVE CONVERSION LOOP COUNTER
- MOV CL,4 ;CL = 4 = SHIFT COUNTER
- MOV AL,[SI] ;AL = FILE BUFFER CHARACTER
- MOV AH,AL ;AH = FILE BUFFER CHARACTER
- CMP AH,20H ;COMPARE AH AN ASCII " "
- JL DPF070 ;BRANCH IF UNDISPLAYABLE
- CMP AH,7EH ;COMPARE AH TO ASCII "~"
- JNG DPF080 ;BRANCH IF DISPLAYABLE
- ;
- ; SET AH TO AN ASCII PERIOD // NON-DISPLAYABLE CHARACTER
- ;
- DPF070:
- MOV AH,"." ;AH = AN ASCII PERIOD
- ;
- ; AH CONTAINS THE DISPLAYABLE ASCII CHARACTER
- ;
- DPF080:
- MOV DS:[BP],AH ;MOVE CHARACTER TO ASCII AREA
- SUB AH,AH ;AH = ZEROS // SET FOR CONVERT
- SHL AX,CL ;POSITION UPPER CL BITS OF AL
- SHR AL,CL ;POSITION LOWER CL BITS OF AL
- XCHG AL,AH ;EXCHANGE CONTENTS OF AL AND AH
- PUSH AX ;SAVE CONTENTS OF AX ON STACK
- MOV BX,OFFSET ASCIIT ;BX = ASCII TABLE ADDRESS
- XLAT ASCIIT ;CONVERT CHARACTER TO HEX
- MOV [DI],AL ;MOVE CHARACTER TO DISPLAY LINE
- INC DI ;INCREMENT STORAGE INDEX
- POP AX ;RESTORE ORIGINAL AX CONTENTS
- MOV CL,8 ;CL = 8 = SHIFT COUNTER
- SHR AX,CL ;POSITION UPPER 8 BITS
- XLAT ASCIIT ;CONVERT CHARACTER TO HEX
- MOV [DI],AL ;MOVE CHARACTER TO DISPLAY LINE
- ADD DI,2 ;INCREMENT DI FOR NEXT BYTE
- INC SI ;INCREMENT SI FOR NEXT BYTE
- INC BP ;INCREMENT BP FOR NEXT BYTE
- POP CX ;RESTORE LOOP CONTROL COUNTER
- LOOP DPF050 ;BRANCH TO CONVERT FULL LINE
- ;
- PAGE
- ;
- ; CONVERT AND SETUP RELATIVE BUFFER OFFSET
- ;
- MOV AX,HEXCNT ;AX = CURRENT BUFFER OFFSET
- MOV DI,OFFSET DPLINE+6 ;DI = DISPLAY LINE OFFSET
- PUSH SI ;SAVE BUFFER INDEX ON STACK
- CALL BDCONV ;BINARY TO DECIMAL CONVERSION
- POP SI ;RESTORE BUFFER INDEX
- MOV DI,OFFSET DPLINE ;DI = DISPLAY LINE OFFSET
- MOV AX,HEXCNT ;AX = CURRENT BUFFER OFFSET
- MOV CX,4 ;CX = LOOP COUNTER (4 BYTES)
- ;
- ; CONVERT HEXADECIMAL TO ASCII // BUFFER OFFSET
- ;
- DPF090:
- PUSH CX ;SAVE LOOP COUNTER ON STACK
- MOV CL,4 ;CL = 4 = SHIFT COUNTER
- PUSH AX ;SAVE CURRENT BUFFER OFFSET
- AND AX,0F000H ;ISOLATE UPPER NIBBLE // 4 BITS
- XCHG AL,AH ;EXCHANGE VALUES IN AL AND AH
- SHR AL,CL ;POSITION 4-BIT NIBBLE
- XLAT ASCIIT ;CONVERT TO HEXADECIMAL BYTE
- MOV [DI],AL ;STORE CONVERTED BYTE // HEX
- INC DI ;INCREMENT BYTE STORAGE INDEX
- POP AX ;RESTORE CONTENTS TO AX
- SHL AX,CL ;POSITION NEXT 4-BIT NIBBLE
- POP CX ;RESTORE THE LOOP COUNTER
- LOOP DPF090 ;LOOP TO CONVERT ALL NIBBLES
- ;
- ; DISPLAY THE LAST LINE CONVERTED
- ;
- ADD HEXCNT,16 ;UPDATE HEX OFFSET COUNTER
- MOV BX,OFFSET DPLINE ;BX = HEXADECIMAL DISPLAY AREA
- MOV CX,80 ;CX = DISPLAY LINE BYTE COUNT
- ;
- ; DISPLAY A CONVERTED BYTE OF DATA
- ;
- DPF100:
- MOV DL,[BX] ;DL = CONVERTED DATA BYTE
- INC BX ;INCREMENT BX TO NEXT BYTE
- MOV AH,02H ;AH = 2 = DISPLAY CHARACTER
- INT 21H ;CALL DOS FOR SERVICE
- LOOP DPF100 ;BRANCH TO DISPLAY NEXT BYTE
- POP CX ;RESTORE BLOCK COUNTER
- LOOP DPF110 ;BRANCH TO PRINT NEXT LINE
- MOV HEXCNT,0 ;RESET THE HEX OFFSET COUNTER
- MOV DX,OFFSET FMFEED ;DX = CR, LF, AND FF BUFFER
- MOV AH,09H ;AH = 9 = WRITE DATA TO DISPLAY
- INT 21H ;CALL DOS FOR SERVICE
- SUB BP,BP ;BP = ZERO - FOR BLOCK NUMBER
- JMP DPF020 ;BRANCH TO READ NEXT BLOCK
- PAGE
- ;
- ; CONVERT AND DISPLAY NEXT 16 BYTES OF DATA
- ;
- DPF110:
- PUSH CX ;SAVE CONTENTS OF LINE COUNTER
- MOV AX,2020H ;AX = 2 ASCII SPACES
- MOV CX,39 ;CX = NUMBER OF WORDS TO SET
- MOV DI,OFFSET DPLINE ;DI = DISPLAY LINE OFFSET
- ;
- ; MOVE ASCII SPACES TO THE DISPLAY LINE BUFFER
- ;
- DPF120:
- MOV [DI],AX ;MOVE SPACES TO DISPLAY LINE
- ADD DI,2 ;INCREMENT DI BY WORDS
- LOOP DPF120 ;BRANCH TO SET ALL WORDS
- ;
- MOV DI,OFFSET DPLINE+12 ;DI = HEXADECIMAL DISPLAY AREA
- MOV BP,OFFSET DPLINE+62 ;BP = ASCII DISPLAY AREA
- MOV CX,16 ;RESET LINE CONVERSION COUNTER
- JMP DPF050 ;BRANCH TO CONVERT NEXT LINE
- ;
- DPFILE ENDP
- PAGE
- ;
- ; BINARY TO DECIMAL (ASCII) CONVERSION
- ;
- BDCONV PROC NEAR
- MOV CX,3 ;CX = LOOP COUNTER
- SUB SI,SI ;SI = ZERO // FOR INDEX
- ;
- ; BINARY TO DECIMAL CONVERSION LOOP
- ;
- BDC010:
- SUB DX,DX ;DX = ZERO // FOR DIVISION
- DIV BINDEC[SI] ;DIVIDE FOR DECIMAL DIGIT
- ADD AL,30H ;ADD 30H FOR ASCII NUMBER
- MOV [DI],AL ;STORE ASCII NUMERIC DIGIT
- INC DI ;INCREMENT FOR NEXT NUMBER
- ADD SI,2 ;INCREMENT SI FOR NEXT NUMBER
- MOV AX,DX ;RESTORE REMAINDER TO AX
- LOOP BDC010 ;BRANCH TO CONVERT ALL DATA
- ;
- ADD AL,30H ;ADD 30H FOR ASCII
- MOV [DI],AL ;STORE ASCII NUMERIC DIGIT
- RET ;RETURN TO CALLER
- ;
- BDCONV ENDP
- ;
- CODSEG ENDS
- END DPFILE